package chat4_tedu.mychatServer;

import chat4_tedu.mychatServer.dao.UserDao;
import chat4_tedu.mychatServer.utils.IOUtil;
import chat4_tedu.mychatServer.vo.Request_Command;
import chat4_tedu.mychatServer.vo.UserInfo;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.HashMap;

public class Server_main {
	//系统所有用户的信息
	private HashMap<String, UserInfo> users;
	public Server_main(){
		users = new HashMap<String, UserInfo>();
	}


	/**
	 * 服务器启动方法
	 */
	public void start(){
		try {
			System.out.println("正在启动服务器");
			ServerSocket ss = new ServerSocket(8088);
			System.out.println("启动服务器完毕");
			while(true){
				Socket s=ss.accept();
				DoServiceForClient dsfc = new DoServiceForClient(s);
				new Thread(dsfc).start();
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
	}




	//服务端会未每个客户端开启一个DoServiceForClient线程，为此线程
	class DoServiceForClient implements Runnable{
		//当前连接客户端的套接字
		private Socket client;
		//当前客户端的输入流
		private InputStream in;
		//当前客户端的输出流
		private OutputStream out;
		//当前客户端对应的用户信息
		private UserInfo userinfo;

		//注册响应
		public static final byte REG_RESPONSE = 1;
		//登陆响应
		public static final byte LOGIN_RESPONSE = REG_RESPONSE + 1;
		//刷新用户列表
		public static final byte USER_LIST_RESPONSE = LOGIN_RESPONSE + 1;
		//私聊响应
		public static final byte MESSAGE_TO_ONE_RESPONSE = USER_LIST_RESPONSE + 1;
		//群聊响应
		public static final byte MESSAGE_TO_ALL_RESPONSE = MESSAGE_TO_ONE_RESPONSE + 1;
		//私人发送文件请求响应
//		public static final byte FILE_TO_ONE_RESPONSE = MESSAGE_TO_ALL_RESPONSE + 1;
		//收件人回执响应
//		public static final byte FILE_TO_ONE_1_RESPONSE = FILE_TO_ONE_RESPONSE + 1;
		//执行私人发送文件响应
//		public static final byte FILE_TO_ONE_2_RESPONSE = FILE_TO_ONE_1_RESPONSE + 1;
		
		//构造方法
		public DoServiceForClient(Socket client){
			this.client = client;
		}
		//线程体
		public void run() {
			try {
				//获取当前连接客户端的输入流，用于获取来自客户端的信息
				in = client.getInputStream();
				out = client.getOutputStream();
				int command = -1;
				while((command = in.read())!=-1){
					switch(command){
						case Request_Command.LOGIN://登陆操作
							System.out.println("message:登陆操作");
							doLogin();
							try {
								reshowFriendList();
							} catch (Exception e) {
								e.printStackTrace();
							}
							break;
						case Request_Command.REG://注册操作
							System.out.println("message:注册操作");
							doReg();
							reshowFriendList();
							break;
						case Request_Command.SEND_TEXT://广播文本信息
							System.out.println("message:广播消息");
							sendMessageToAll();
							break;
						/*case Request_Command.SEND_TEXT_TO_ONE://文本私聊
							System.out.println("message:私聊消息");
							sendMessageToOne();
							break;
						//广播文件
						case Request_Command.SEND_FILE:
							break;*/
						//请求个人传送文件
						/*case Request_Command.SEND_FILE_TO_ONE:
							System.out.println("message:请求传送文件至私人");
							sendFileToOne();
							break;
						//请求回复发件人结果
						case Request_Command.SEND_FILE_TO_ONE_1:
							System.out.println("message:回复是否接收文件");
							sendFileToOne1();
							break;
						//请求开始传送文件
						case Request_Command.SEND_FILE_TO_ONE_2:
							System.out.println("message:开始向私人传送文件");
							sendFileToOne2();
							break;*/
					}
					
				}
			} catch (Exception e) {
				//e.printStackTrace();
			} finally{
				//从共享中删除当前用户

				if( users!=null && users.size()!=0 && userinfo !=null&&userinfo.getUsername()!=null){
					System.out.println("下线一个客户端之前，在线人数为："+users.size());
					users.remove(userinfo.getUsername());
					System.out.println(userinfo.getSocket().getInetAddress()+"客户端下线了");
					System.out.println("下线一个客户端之后，在线人数为："+users.size());
				}
				//刷新所有客户端的好友列表
				try {
					reshowFriendList();
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
			
		}





		/**
		 * 私聊功能
		 */
		/*public void sendMessageToOne()throws Exception{
			//获取聊天对象
			String target = IOUtil.readString(in);
			//获取消息
			String message = IOUtil.readString(in);
			//获取对方输出流
			try {
				OutputStream out = users.get(target).getSocket().getOutputStream();
				IOUtil.writeShort(Response_Command.MESSAGE_TO_ONE_RESPONSE, out);
				//发送当前用户给目标
				IOUtil.writeString(userinfo.getUsername(), out);
				IOUtil.writeString(message, out);
			} catch (Exception e) {
				throw e;
			}

		}*/






		//登陆方法
		public void doLogin()throws Exception{
			try{
				//获取用户名
				String username = IOUtil.readString(in);
				//获取密码
				String password = IOUtil.readString(in);
				if(!checkUserInfoHasLoginByUserName(username)){
					UserInfo user = new UserInfo(username,password);
					if(UserDao.login(user)){
						userinfo = user;
						userinfo.setSocket(client);
						//存入共享(更新服务端的好友列表)
						users.put(username,userinfo);
						System.out.println("一个用户登录成功,ip:"+client.getInetAddress() +",在线人数：" +users.size());
						reshowFriendList();//更新客户端的好友列表
						//发送响应
						IOUtil.writeShort(LOGIN_RESPONSE, out);
						IOUtil.writeString("loginSuccess", out);
						//刷新所有客户端的好友列表
					}else{
						IOUtil.writeShort(LOGIN_RESPONSE, out);
						IOUtil.writeString("用户名或密码错误...", out);
					}
				}else{
					IOUtil.writeShort(LOGIN_RESPONSE, out);
					IOUtil.writeString("账号:"+username+" 处于登陆状态...", out);
				}
			}catch(Exception e){
				IOUtil.writeShort(LOGIN_RESPONSE, out);
				IOUtil.writeString("登陆异常"+e.getMessage(), out);
				throw e;
			}
		}

		//刷新所有用户的好友列表
		public void reshowFriendList()throws Exception{
			StringBuffer friendsInfo=new StringBuffer();
			for(String user:users.keySet()){
				friendsInfo.append(user+",");
			}
			for(UserInfo userinfo : users.values()){
				try{
					IOUtil.writeShort(USER_LIST_RESPONSE, userinfo.getSocket().getOutputStream());
					IOUtil.writeString(friendsInfo.toString(), userinfo.getSocket().getOutputStream());
				}catch(Exception e){
					throw e;
				}
			}
		}

		//判断当前用户是否处于登陆状态(集合中是否有此用户<上边的doLogin方法中调用了>)
		public boolean checkUserInfoHasLoginByUserName(String username){
			return users.containsKey(username);
		}


		//注册方法
		public void doReg()throws Exception{
			int flag=-1;
			try{
				//获取用户名
				String username = IOUtil.readString(in);
				//获取密码
				String password = IOUtil.readString(in);
				UserDao.addUser(new UserInfo(username,password));
				flag=1;
				//存入共享
				userinfo = new UserInfo();
				userinfo.setUsername(username);
				userinfo.setPassword(password);
				userinfo.setSocket(client);
				users.put(username, userinfo);
			}catch(Exception e){
				//发送响应
				IOUtil.writeShort(REG_RESPONSE, out);
				IOUtil.writeString(e.getMessage(), out);
				flag=-1;
				//throw e;
			}
			if(flag==1){
				//发送响应
				IOUtil.writeShort(REG_RESPONSE, out);
				IOUtil.writeString("regSuccess", out);
			}
			//刷新所有客户端的好友列表
			reshowFriendList();
		}




		/**
		 * 广播功能
		 */
		public void sendMessageToAll()throws Exception{
			//用IOUtil工具类读取某客户端发送的消息
			String message = IOUtil.readString(in);
			//获取对方输出流
			try {
				for(UserInfo userInfo : users.values()){
					//不用转发给自己
					if(userInfo.getUsername().equals(userinfo.getUsername())){
						continue;
					}
					OutputStream out = userInfo.getSocket().getOutputStream();

					IOUtil.writeShort(MESSAGE_TO_ALL_RESPONSE, out);
					IOUtil.writeString(userinfo.getUsername(), out);//发送当前用户名给所有人(用来说明此消息是来自哪个客户端发送的)
					IOUtil.writeString(message, out);//发送接收到的消息给所有人
				}
			} catch (Exception e) {
				throw e;
			}


		}



	}




	public static void main(String []args){
		Server_main server = new Server_main();
		server.start();
	}


}
